External validation, recalibration, and clinical utility of the prognostic model kidney failure risk equation in patients with CKD stages G3-4: a nationwide retrospective cohort analysis in Peru

Main Analysis - Winsorization 1.5%: 3. Descriptive Analysis

Author

Percy Soto Becerra

1 Setup

rm(list = ls())

# Use pacman to check whether packages are installed, if not load
if (!require("pacman")) install.packages("pacman")
library(pacman)

# Unload all package to begin in a session with only base packages
pacman::p_unload(all)

# Install packages
pacman::p_load(
  here, 
  rio, 
  tidyverse, 
  janitor, 
  knitr, 
  kableExtra,
  flextable, 
  gtsummary,
  patchwork,
  cowplot, 
  kableExtra,
  ggsci, 
  scales, 
  mice, 
  sf, 
  rnaturalearth, 
  viridis,
  RColorBrewer,
  ggmagnify, 
  survival, 
  tidycmprsk, 
  cmprsk,
  survminer
)

source(here("Code", "source", "kfre_pi.R"))
source(here("Code", "source", "kfre_pr.R"))

mypal <- pal_npg("nrc")(9)
mypal
[1] "#E64B35FF" "#4DBBD5FF" "#00A087FF" "#3C5488FF" "#F39B7FFF" "#8491B4FF"
[7] "#91D1C2FF" "#DC0000FF" "#7E6148FF"
## Revisar:; https://amices.org/ggmice/index.html

2 Load data

# Import data
imp.datosA <- readRDS(here::here("Data", "Tidy", "Main-Winsorize-1_5", "data_impA.rds")) 

# Create data for CKD 3b-4 (subset of CKD3a-4)
imp.datosA <- imp.datosA |> 
  mutate(grf_cat = droplevels(grf_cat)) 

3 Pre-processing data

nsize <- nrow(imp.datosA |> filter(.imp == 0))

imp.datosA <- imp.datosA |> 
  mutate(
    acr = exp(log_acr), 
    urine_crea = exp(log_urine_crea), 
    urine_album = exp(log_urine_album), 
    acr_cat = case_when(acr < 30 ~ "A1", 
                        acr <= 300 & acr >= 30 ~ "A2", 
                        acr > 300 ~ "A3", 
                        TRUE ~ as.character(NA)),
    ckd_class = case_when(
      grf_cat %in% c("G1", "G2") & acr_cat == "A1" ~ "Low risk", 
      (grf_cat %in% c("G3a") & acr_cat == "A1") | 
        (grf_cat %in% c("G1", "G2") & acr_cat == "A2") ~ "Moderately increased risk", 
      (grf_cat %in% c("G3b") & acr_cat == "A1") | 
        (grf_cat == "G3a" & acr_cat == "A2") | 
        (grf_cat %in% c("G1", "G2") & acr_cat == "A3") ~ "High risk", 
      (grf_cat %in% c("G4", "G5") & acr_cat == "A1") | 
        (grf_cat %in% c("G3b", "G4", "G5") & acr_cat == "A2") | 
        (grf_cat %in% c("G3a", "G3b", "G4", "G5") & acr_cat == "A3") ~ "Very high risk"
    ), 
    ckd_class = factor(ckd_class, 
                       levels = c("Low risk", "Moderately increased risk", 
                                  "High risk", "Very high risk")), 
    # cas = fct_rev(fct_infreq(cas)), 
    # cas2 = fct_rev(fct_infreq(cas2)), 
    acr_miss = if_else(!is.na(acr), "All variable with complete data", "At least 1 variable with missing data"), 
    across(c(hta, dm, death2y, death5y), ~ 
             case_when(.x == "1" ~ "Yes", 
                       .x == "0" ~ "No",
                       TRUE ~ as.character(NA))), 
    region_peru = case_when(
      cas %in% c("Lima - Sabogal", 
                 "Lima - Almenara", 
                 "Lima - Rebagliati") ~ "Lima Metropolitana",
      cas == "Amazonas" ~ "Amazonas",
      cas == "Ancash" ~ "Ancash",
      cas == "Apurimac" ~ "Apurímac",
      cas == "Arequipa" ~ "Arequipa",
      cas == "Ayacucho" ~ "Ayacucho",
      cas == "Cajamarca" ~ "Cajamarca",
      cas == "Cusco" ~ "Cusco",
      cas == "Huancavelica" ~ "Huancavelica",
      cas == "Huanuco" ~ "Huánuco",
      cas == "Huaraz" ~ "Ancash",
      cas == "Juliaca" ~ "Puno",
      cas == "Junin" ~ "Junín",
      cas == "Lambayeque" ~ "Lambayeque",
      cas == "La Libertad" ~ "La Libertad",
      cas == "Loreto" ~ "Loreto",
      cas == "Madre De Dios" ~ "Madre de Dios",
      cas == "Moquegua" ~ "Moquegua",
      cas == "Moyobamba" ~ "San Martín",
      cas == "Pasco" ~ "Pasco",
      cas == "Piura" ~ "Piura",
      cas == "Puno" ~ "Puno",
      cas == "Ica" ~ "Ica",
      cas == "Tacna" ~ "Tacna",
      cas == "Tarapoto" ~ "San Martín",
      cas == "Tumbes" ~ "Tumbes",
      cas == "Ucayali" ~ "Ucayali",
      TRUE ~ "Other" # Para manejar cualquier otro caso no contemplado
    ), 
    cas = case_when(
      cas %in% c("KAELIN", "Lima - Rebagliati: JB") ~ "Lima: Rebagliati",
      cas == "Lima - Almenara" ~ "Lima: Almenara",
      cas == "Lima - Sabogal" ~ "Lima y Callao: Sabogal",
      cas == "Amazonas" ~ "Amazonas",
      cas == "Ancash" ~ "Ancash: Anchas (except Huaraz)",
      cas == "Apurimac" ~ "Apurímac",
      cas == "Arequipa" ~ "Arequipa",
      cas == "Ayacucho" ~ "Ayacucho",
      cas == "Cajamarca" ~ "Cajamarca",
      cas == "Cusco" ~ "Cusco",
      cas == "Huancavelica" ~ "Huancavelica",
      cas == "Huanuco" ~ "Huánuco",
      cas == "Huaraz" ~ "Ancash: Huaraz",
      cas == "Juliaca" ~ "Puno: Juliaca",
      cas == "Junin" ~ "Junín",
      cas == "Lambayeque" ~ "Lambayeque",
      cas == "La Libertad" ~ "La Libertad",
      cas == "Loreto" ~ "Loreto",
      cas == "Madre De Dios" ~ "Madre de Dios",
      cas == "Moquegua" ~ "Moquegua",
      cas == "Moyobamba" ~ "San Martín: Moyobamba",
      cas == "Pasco" ~ "Pasco",
      cas == "Piura" ~ "Piura",
      cas == "Puno" ~ "Puno: Puno (except Juliaca)",
      cas == "Ica" ~ "Ica",
      cas == "Tacna" ~ "Tacna",
      cas == "Tarapoto" ~ "San Martín",
      cas == "Tumbes" ~ "Tumbes",
      cas == "Ucayali" ~ "Ucayali",
      TRUE ~ "Other" # Para manejar cualquier otro caso no contemplado
    ), 
    cas_cat = case_when(
      region_peru %in% c("Lima Metropolitana") ~ "Metropolitan Lima",
      TRUE ~ "Other Regions"
    ), 
    risk2y = kfre_pr(imp.datosA, 2),
    risk5y = kfre_pr(imp.datosA, 5)) |> 
  labelled::set_variable_labels(
    sex = "Sex", 
    age = "Age (years)", 
    cas = "EsSalud Network", 
    cas_cat = "EsSalud Network", 
    crea = "Serum Creatinine (mg/dL)", 
    eGFR_ckdepi = "eGFR using CKD-EPI (ml/min/1.73m²)", 
    acr = "Albumin-Creatinine Ratio (mg/g)", 
    urine_album = "Urine Albumin (mg/dl)", 
    urine_crea = "Urine Creatinine (mg/dL)", 
    hta = "Hypertension", 
    dm = "Diabetes Mellitus", 
    grf_cat = "eGFR Categories", 
    acr_cat = "Persistent Albuminuria Categories", 
    ckd_class = "CKD KDIGO Classification", 
    eventd5ylab = "5-Year Outcome", 
    eventd2ylab = "2-Year Outcome", 
    eventd5y = "5-Year Outcome", 
    death5y = "5-Year Mortality", 
    death2y = "2-Year Mortality")

4 Table 1

# Tabla 1a
survey::svydesign(~1, data = imp.datosA |> filter(.imp != 0), weights = ~wg) %>%
  gtsummary::tbl_svysummary(
    include = c(sex, age, cas_cat, hta, dm, acr_cat, grf_cat, ckd_class, crea,
                eGFR_ckdepi, acr, urine_album, urine_crea,  death2y, 
                eventd2ylab, death5y, eventd5ylab), 
    type = list(all_continuous() ~ "continuous2", 
                c(hta, dm, death2y, death5y) ~ "categorical"),
    statistic = all_continuous() ~ c(
      "{mean} ({sd})",
      "{median} ({p25} - {p75})", 
      "{min} - {max}"
    ),
    digits = list(all_continuous() ~ c(1, 1, 1, 1), 
                  all_categorical() ~ c(0, 1)), 
    missing_text = "Missing"
  ) |> 
  bold_labels() |>  
  modify_caption("Table 1. Baseline characteristics of the study population") |> 
  modify_footnote(everything() ~ NA) -> tab1a

tab1a |>  
  as_flex_table() |>  
  flextable::save_as_docx(path = here("Tables", "Main-Winsorize-1_5", "Table1_Imputed.docx"))

tab1a |>  
  gtsummary::as_kable_extra() |> 
  kableExtra::kable_styling("striped")
Table 1. Baseline characteristics of the study population
Characteristic N = 30,031
Sex
Femenino 13,097 (43.6%)
Masculino 16,934 (56.4%)
Age (years)
Mean (SD) 73.8 (11.1)
Median (Q1 - Q3) 75.0 (67.0 - 82.0)
Min - Max 18.0 - 109.0
EsSalud Network
Metropolitan Lima 14,784 (49.2%)
Other Regions 15,247 (50.8%)
Hypertension
No 7,254 (24.2%)
Yes 22,777 (75.8%)
Diabetes Mellitus
No 17,567 (58.5%)
Yes 12,464 (41.5%)
Persistent Albuminuria Categories
A1 14,662 (48.8%)
A2 10,095 (33.6%)
A3 5,274 (17.6%)
eGFR Categories
G3a 18,491 (61.6%)
G3b 8,201 (27.3%)
G4 3,339 (11.1%)
CKD KDIGO Classification
Low risk 0 (0.0%)
Moderately increased risk 9,403 (31.3%)
High risk 10,169 (33.9%)
Very high risk 10,459 (34.8%)
Serum Creatinine (mg/dL)
Mean (SD) 1.4 (0.4)
Median (Q1 - Q3) 1.3 (1.2 - 1.6)
Min - Max 0.9 - 4.5
eGFR using CKD-EPI (ml/min/1.73m²)
Mean (SD) 45.9 (10.8)
Median (Q1 - Q3) 48.5 (39.4 - 54.5)
Min - Max 15.0 - 60.0
Albumin-Creatinine Ratio (mg/g)
Mean (SD) 802.1 (3,534.1)
Median (Q1 - Q3) 32.0 (8.1 - 160.3)
Min - Max 0.6 - 27,817.5
Urine Albumin (mg/dl)
Mean (SD) 35.8 (161.5)
Median (Q1 - Q3) 1.6 (0.4 - 8.4)
Min - Max 0.0 - 1,365.2
Urine Creatinine (mg/dL)
Mean (SD) 60.8 (50.5)
Median (Q1 - Q3) 49.2 (27.0 - 85.0)
Min - Max 0.1 - 221.3
2-Year Mortality
No 27,640 (92.0%)
Yes 2,391 (8.0%)
2-Year Outcome
Alive w/o Kidney Failure 27,227 (90.7%)
Kidney Failure 793 (2.6%)
Death w/o Kidney Failure 2,011 (6.7%)
5-Year Mortality
No 24,261 (80.8%)
Yes 5,770 (19.2%)
5-Year Outcome
Alive w/o Kidney Failure 23,579 (78.5%)
Kidney Failure 1,308 (4.4%)
Death w/o Kidney Failure 5,144 (17.1%)

5 Table Sup - Comparison between Imputed, Available and CCA analysis

# Tabla S1b . Available data 
imp.datosA |> 
  filter(.imp == 0) |> 
  gtsummary::tbl_summary(
    include = c(sex, age, cas_cat, hta, dm, acr_cat, grf_cat, ckd_class, crea,
                eGFR_ckdepi, acr, urine_album, urine_crea,  death2y, 
                eventd2ylab, death5y, eventd5ylab), 
    type = list(all_continuous() ~ "continuous2", 
                c(hta, dm, death2y, death5y) ~ "categorical"),
    statistic = all_continuous() ~ c(
      "{mean} ({sd})",
      "{median} ({p25} - {p75})", 
      "{min} - {max}"
    ),
    digits = list(all_continuous() ~ c(1, 1, 1, 1), 
                  all_categorical() ~ c(0, 1)), 
    missing_text = "Missing"
  ) |> 
  bold_labels()  |>   
  modify_footnote(everything() ~ NA) -> tabS1a_available

# Tabla S1b . Available data 
imp.datosA |> 
  filter(.imp == 0) |> 
  gtsummary::tbl_summary(
    include = c(sex, age, cas_cat, hta, dm, acr_cat, grf_cat, ckd_class, crea,
                eGFR_ckdepi, acr, urine_album, urine_crea,  death2y, 
                eventd2ylab, death5y, eventd5ylab), 
    by = acr_miss,
    type = list(all_continuous() ~ "continuous2", 
                c(hta, dm, death2y, death5y) ~ "categorical"),
    statistic = all_continuous() ~ c(
      "{mean} ({sd})",
      "{median} ({p25} - {p75})", 
      "{min} - {max}"
    ),
    digits = list(all_continuous() ~ c(1, 1, 1, 1), 
                  all_categorical() ~ c(0, 1)), 
    missing_text = "Missing", 
    percent = "row"
  ) |> 
  bold_labels() |>  
  add_p(include = c(sex, age, cas_cat, hta, dm, grf_cat, crea,
                eGFR_ckdepi, urine_album, urine_crea,  death2y, 
                eventd2ylab, death5y, eventd5ylab)) |>  
  separate_p_footnotes() |>  
  modify_footnote(everything() ~ NA) -> tabS1a_miss

tbl_merge(list(tab1a, tabS1a_available, tabS1a_miss), 
          tab_spanner = c("**Imputed Data**\n**(% col)**", 
                          "**Available Data**\n**(% col)**", 
                          "**Complete data in all variables used for multiple imputation**\n**(% row)**")) |>  
  modify_caption("Table. Baseline characteristics of the study population with CKD Stages 3a-3b-4 according missing data in KFRE's predicted risk") |> 
  bold_labels() -> tabS1

tabS1 %>% 
  as_flex_table() %>% 
  flextable::save_as_docx(path = here("Tables", "Main-Winsorize-1_5", "Table_Sup_S1_by_missing_3a4.docx"))

tabS1 %>% 
  gtsummary::as_kable_extra() %>%
  kableExtra::kable_styling("striped")
Table. Baseline characteristics of the study population with CKD Stages 3a-3b-4 according missing data in KFRE's predicted risk
Imputed Data
(% col)
Available Data
(% col)
Complete data in all variables used for multiple imputation
(% row)
Characteristic N = 30,031 N = 30,031 All variable with complete data
N = 9,818
At least 1 variable with missing data
N = 20,213
p-value
Sex <0.001
Femenino 13,097 (43.6%) 13,097 (43.6%) 2,591 (19.8%) 10,506 (80.2%)
Masculino 16,934 (56.4%) 16,934 (56.4%) 7,227 (42.7%) 9,707 (57.3%)
Age (years) <0.001
Mean (SD) 73.8 (11.1) 73.8 (11.1) 75.6 (11.6) 73.0 (10.8)
Median (Q1 - Q3) 75.0 (67.0 - 82.0) 75.0 (67.0 - 82.0) 76.0 (69.0 - 84.0) 74.0 (66.0 - 81.0)
Min - Max 18.0 - 109.0 18.0 - 109.0 18.0 - 109.0 22.0 - 108.0
EsSalud Network <0.001
Metropolitan Lima 14,784 (49.2%) 14,784 (49.2%) 8,897 (60.2%) 5,887 (39.8%)
Other Regions 15,247 (50.8%) 15,247 (50.8%) 921 (6.0%) 14,326 (94.0%)
Hypertension <0.001
No 7,254 (24.2%) 6,620 (27.2%) 325 (4.9%) 6,295 (95.1%)
Yes 22,777 (75.8%) 17,696 (72.8%) 4,736 (26.8%) 12,960 (73.2%)
Missing 5,715 4,757 958
Diabetes Mellitus <0.001
No 17,567 (58.5%) 13,643 (63.7%) 746 (5.5%) 12,897 (94.5%)
Yes 12,464 (41.5%) 7,782 (36.3%) 2,231 (28.7%) 5,551 (71.3%)
Missing 8,606 6,841 1,765
Persistent Albuminuria Categories
A1 14,662 (48.8%) 5,183 (52.8%) 5,183 (100.0%) 0 (0.0%)
A2 10,095 (33.6%) 2,874 (29.3%) 2,874 (100.0%) 0 (0.0%)
A3 5,274 (17.6%) 1,761 (17.9%) 1,761 (100.0%) 0 (0.0%)
Missing 20,213 0 20,213
eGFR Categories <0.001
G3a 18,491 (61.6%) 18,491 (61.6%) 5,043 (27.3%) 13,448 (72.7%)
G3b 8,201 (27.3%) 8,201 (27.3%) 3,423 (41.7%) 4,778 (58.3%)
G4 3,339 (11.1%) 3,339 (11.1%) 1,352 (40.5%) 1,987 (59.5%)
CKD KDIGO Classification
Low risk 0 (0.0%) 0 (0.0%) 0 (NA%) 0 (NA%)
Moderately increased risk 9,403 (31.3%) 3,106 (31.6%) 3,106 (100.0%) 0 (0.0%)
High risk 10,169 (33.9%) 3,102 (31.6%) 3,102 (100.0%) 0 (0.0%)
Very high risk 10,459 (34.8%) 3,610 (36.8%) 3,610 (100.0%) 0 (0.0%)
Missing 20,213 0 20,213
Serum Creatinine (mg/dL) <0.001
Mean (SD) 1.4 (0.4) 1.4 (0.4) 1.5 (0.4) 1.4 (0.4)
Median (Q1 - Q3) 1.3 (1.2 - 1.6) 1.3 (1.2 - 1.6) 1.4 (1.3 - 1.7) 1.3 (1.1 - 1.5)
Min - Max 0.9 - 4.5 0.9 - 4.5 0.9 - 4.1 0.9 - 4.5
eGFR using CKD-EPI (ml/min/1.73m²) <0.001
Mean (SD) 45.9 (10.8) 45.9 (10.8) 43.2 (10.4) 47.2 (10.8)
Median (Q1 - Q3) 48.5 (39.4 - 54.5) 48.5 (39.4 - 54.5) 45.4 (36.5 - 51.3) 50.1 (41.3 - 55.7)
Min - Max 15.0 - 60.0 15.0 - 60.0 15.0 - 60.0 15.0 - 60.0
Albumin-Creatinine Ratio (mg/g)
Mean (SD) 802.1 (3,534.1) 984.5 (4,075.4) 984.5 (4,075.4) NA (NA)
Median (Q1 - Q3) 32.0 (8.1 - 160.3) 25.5 (5.8 - 155.1) 25.5 (5.8 - 155.1) NA (NA - NA)
Min - Max 0.6 - 27,817.5 0.6 - 27,817.5 0.6 - 27,817.5 Inf - -Inf
Missing 20,213 0 20,213
Urine Albumin (mg/dl) 0.034
Mean (SD) 35.8 (161.5) 56.5 (212.8) 56.5 (212.9) 58.3 (210.3)
Median (Q1 - Q3) 1.6 (0.4 - 8.4) 1.7 (0.4 - 11.5) 1.7 (0.4 - 11.5) 2.9 (0.7 - 16.0)
Min - Max 0.0 - 1,365.2 0.0 - 1,365.2 0.0 - 1,365.2 0.0 - 1,365.2
Missing 21,249 1,186 20,063
Urine Creatinine (mg/dL) <0.001
Mean (SD) 60.8 (50.5) 65.9 (45.0) 76.5 (42.7) 46.4 (42.6)
Median (Q1 - Q3) 49.2 (27.0 - 85.0) 58.3 (36.7 - 85.0) 69.6 (45.7 - 91.4) 40.9 (10.6 - 64.9)
Min - Max 0.1 - 221.3 0.1 - 221.3 0.1 - 221.3 0.1 - 221.3
Missing 16,739 1,187 15,552
2-Year Mortality <0.001
No 27,640 (92.0%) 27,640 (92.0%) 8,801 (31.8%) 18,839 (68.2%)
Yes 2,391 (8.0%) 2,391 (8.0%) 1,017 (42.5%) 1,374 (57.5%)
2-Year Outcome <0.001
Alive w/o Kidney Failure 27,227 (90.7%) 27,227 (90.7%) 8,661 (31.8%) 18,566 (68.2%)
Kidney Failure 793 (2.6%) 793 (2.6%) 348 (43.9%) 445 (56.1%)
Death w/o Kidney Failure 2,011 (6.7%) 2,011 (6.7%) 809 (40.2%) 1,202 (59.8%)
5-Year Mortality <0.001
No 24,261 (80.8%) 24,261 (80.8%) 7,480 (30.8%) 16,781 (69.2%)
Yes 5,770 (19.2%) 5,770 (19.2%) 2,338 (40.5%) 3,432 (59.5%)
5-Year Outcome <0.001
Alive w/o Kidney Failure 23,579 (78.5%) 23,579 (78.5%) 7,236 (30.7%) 16,343 (69.3%)
Kidney Failure 1,308 (4.4%) 1,308 (4.4%) 574 (43.9%) 734 (56.1%)
Death w/o Kidney Failure 5,144 (17.1%) 5,144 (17.1%) 2,008 (39.0%) 3,136 (61.0%)
1 Pearson's Chi-squared test
2 Wilcoxon rank sum test

6 Table Sup - Comparison between Outcome distribution

# Tabla 1a
survey::svydesign(~1, data = imp.datosA |> filter(.imp != 0), weights = ~wg) %>%
  gtsummary::tbl_svysummary(
    include = c(sex, age, cas_cat, hta, dm, acr_cat, grf_cat, ckd_class, crea,
                eGFR_ckdepi, acr, urine_album, urine_crea,  death2y, 
                eventd2ylab, death5y, eventd5ylab), 
    type = list(all_continuous() ~ "continuous2", 
                c(hta, dm, death2y, death5y) ~ "categorical"),
    by = eventd5ylab, 
    statistic = all_continuous() ~ c(
      "{mean} ({sd})",
      "{median} ({p25} - {p75})", 
      "{min} - {max}"
    ),
    digits = list(all_continuous() ~ c(1, 1, 1, 1), 
                  all_categorical() ~ c(0, 1)), 
    missing_text = "Missing", 
    percent = "row"
  ) |> 
  bold_labels() |>  
  modify_footnote(everything() ~ NA) -> tabS2a

imp.datosA |> 
  filter(.imp == 0) |> 
  gtsummary::tbl_summary(
    include = c(sex, age, cas_cat, hta, dm, acr_cat, grf_cat, ckd_class, crea,
                eGFR_ckdepi, acr, urine_album, urine_crea,  death2y, 
                eventd2ylab, death5y, eventd5ylab), 
    by = eventd5ylab, 
    type = list(all_continuous() ~ "continuous2", 
                c(hta, dm, death2y, death5y) ~ "categorical"),
    statistic = all_continuous() ~ c(
      "{mean} ({sd})",
      "{median} ({p25} - {p75})", 
      "{min} - {max}"
    ),
    digits = list(all_continuous() ~ c(1, 1, 1, 1), 
                  all_categorical() ~ c(0, 1)), 
    missing_text = "Missing", 
    percent = "row"
  ) |> 
  bold_labels() |>  
  modify_footnote(everything() ~ NA) -> tabS2b

tbl_merge(list(tabS2a, tabS2b), 
          tab_spanner = c("**Imputed Data**\n**(% columna)**", 
                          "**Availabe Data**\n**(% fila)**")) |>  
  modify_caption("Table. Baseline characteristics of the study population with CKD Stages 3a-3b-4 according missing data in KFRE's predicted risk") |> 
  bold_labels() -> tabS2

tabS2 %>% 
  as_flex_table() %>% 
  flextable::save_as_docx(path = here("Tables", "Main-Winsorize-1_5", "Table_Sup_S2_Outcome_by_missing_3a4.docx"))

tabS2 %>% 
  gtsummary::as_kable_extra() %>%
  kableExtra::kable_styling("striped")
Table. Baseline characteristics of the study population with CKD Stages 3a-3b-4 according missing data in KFRE's predicted risk
Imputed Data
(% columna)
Availabe Data
(% fila)
Characteristic Alive w/o Kidney Failure
N = 23,579
Kidney Failure
N = 1,308
Death w/o Kidney Failure
N = 5,144
Alive w/o Kidney Failure
N = 23,579
Kidney Failure
N = 1,308
Death w/o Kidney Failure
N = 5,144
Sex
Femenino 11,078 (84.6%) 479 (3.7%) 1,540 (11.8%) 11,078 (84.6%) 479 (3.7%) 1,540 (11.8%)
Masculino 12,501 (73.8%) 829 (4.9%) 3,604 (21.3%) 12,501 (73.8%) 829 (4.9%) 3,604 (21.3%)
Age (years)
Mean (SD) 72.8 (10.8) 70.3 (13.7) 79.5 (10.0) 72.8 (10.8) 70.3 (13.7) 79.5 (10.0)
Median (Q1 - Q3) 73.0 (66.0 - 80.0) 71.0 (62.0 - 80.0) 80.0 (74.0 - 86.0) 73.0 (66.0 - 80.0) 71.0 (62.0 - 80.0) 80.5 (74.0 - 86.0)
Min - Max 18.0 - 109.0 24.0 - 103.0 26.0 - 107.0 18.0 - 109.0 24.0 - 103.0 26.0 - 107.0
EsSalud Network
Metropolitan Lima 10,770 (72.8%) 1,097 (7.4%) 2,917 (19.7%) 10,770 (72.8%) 1,097 (7.4%) 2,917 (19.7%)
Other Regions 12,809 (84.0%) 211 (1.4%) 2,227 (14.6%) 12,809 (84.0%) 211 (1.4%) 2,227 (14.6%)
Hypertension
No 5,886 (81.1%) 145 (2.0%) 1,223 (16.9%) 5,416 (81.8%) 93 (1.4%) 1,111 (16.8%)
Yes 17,693 (77.7%) 1,163 (5.1%) 3,921 (17.2%) 13,998 (79.1%) 713 (4.0%) 2,985 (16.9%)
Missing 4,165 502 1,048
Diabetes Mellitus
No 14,337 (81.6%) 438 (2.5%) 2,792 (15.9%) 11,491 (84.2%) 118 (0.9%) 2,034 (14.9%)
Yes 9,242 (74.1%) 870 (7.0%) 2,352 (18.9%) 5,857 (75.3%) 476 (6.1%) 1,449 (18.6%)
Missing 6,231 714 1,661
Persistent Albuminuria Categories
A1 11,767 (80.3%) 448 (3.1%) 2,447 (16.7%) 4,116 (79.4%) 109 (2.1%) 958 (18.5%)
A2 7,899 (78.3%) 427 (4.2%) 1,768 (17.5%) 2,049 (71.3%) 164 (5.7%) 661 (23.0%)
A3 3,912 (74.2%) 433 (8.2%) 929 (17.6%) 1,071 (60.8%) 301 (17.1%) 389 (22.1%)
Missing 16,343 734 3,136
eGFR Categories
G3a 15,880 (85.9%) 138 (0.7%) 2,473 (13.4%) 15,880 (85.9%) 138 (0.7%) 2,473 (13.4%)
G3b 5,956 (72.6%) 388 (4.7%) 1,857 (22.6%) 5,956 (72.6%) 388 (4.7%) 1,857 (22.6%)
G4 1,743 (52.2%) 782 (23.4%) 814 (24.4%) 1,743 (52.2%) 782 (23.4%) 814 (24.4%)
CKD KDIGO Classification
Low risk 0 (NA%) 0 (NA%) 0 (NA%) 0 (NA%) 0 (NA%) 0 (NA%)
Moderately increased risk 8,123 (86.4%) 53 (0.6%) 1,226 (13.0%) 2,650 (85.3%) 20 (0.6%) 436 (14.0%)
High risk 8,228 (80.9%) 182 (1.8%) 1,760 (17.3%) 2,374 (76.5%) 64 (2.1%) 664 (21.4%)
Very high risk 7,227 (69.1%) 1,073 (10.3%) 2,158 (20.6%) 2,212 (61.3%) 490 (13.6%) 908 (25.2%)
Missing 16,343 734 3,136
Serum Creatinine (mg/dL)
Mean (SD) 1.4 (0.4) 2.2 (0.6) 1.5 (0.4) 1.4 (0.4) 2.2 (0.6) 1.5 (0.4)
Median (Q1 - Q3) 1.3 (1.1 - 1.5) 2.1 (1.7 - 2.6) 1.4 (1.2 - 1.7) 1.3 (1.1 - 1.5) 2.1 (1.7 - 2.6) 1.4 (1.2 - 1.7)
Min - Max 0.9 - 4.5 1.0 - 4.2 0.9 - 4.1 0.9 - 4.5 1.0 - 4.2 0.9 - 4.1
eGFR using CKD-EPI (ml/min/1.73m²)
Mean (SD) 47.5 (9.8) 29.4 (10.5) 42.6 (11.1) 47.5 (9.8) 29.4 (10.5) 42.6 (11.1)
Median (Q1 - Q3) 49.8 (42.1 - 55.1) 27.0 (21.0 - 35.7) 44.4 (34.9 - 51.6) 49.8 (42.1 - 55.1) 27.0 (21.0 - 35.7) 44.4 (35.0 - 51.6)
Min - Max 15.0 - 60.0 15.0 - 59.9 15.0 - 60.0 15.0 - 60.0 15.0 - 59.9 15.0 - 60.0
Albumin-Creatinine Ratio (mg/g)
Mean (SD) 713.1 (3,268.3) 2,497.2 (6,711.4) 778.9 (3,425.7) 705.6 (3,309.6) 4,731.4 (8,953.5) 918.3 (3,816.7)
Median (Q1 - Q3) 30.2 (7.6 - 145.6) 93.4 (16.1 - 617.5) 34.4 (9.0 - 167.0) 19.9 (5.2 - 110.2) 372.6 (65.4 - 2,745.1) 34.1 (8.7 - 181.8)
Min - Max 0.6 - 27,817.5 0.6 - 27,817.5 0.6 - 27,817.5 0.6 - 27,817.5 0.6 - 27,817.5 0.6 - 27,817.5
Missing 16,343 734 3,136
Urine Albumin (mg/dl)
Mean (SD) 31.0 (145.4) 120.5 (328.2) 36.4 (161.2) 41.4 (173.3) 241.8 (445.7) 51.1 (197.3)
Median (Q1 - Q3) 1.5 (0.4 - 7.5) 4.9 (0.8 - 26.5) 1.9 (0.5 - 9.4) 1.3 (0.4 - 8.0) 18.6 (4.2 - 154.0) 2.4 (0.6 - 12.4)
Min - Max 0.0 - 1,365.2 0.0 - 1,365.2 0.0 - 1,365.2 0.0 - 1,365.2 0.0 - 1,365.2 0.0 - 1,365.2
Missing 17,225 735 3,289
Urine Creatinine (mg/dL)
Mean (SD) 60.7 (51.1) 58.5 (43.6) 62.0 (49.2) 66.3 (46.2) 59.3 (33.3) 66.6 (43.3)
Median (Q1 - Q3) 48.6 (26.0 - 85.0) 50.0 (31.2 - 78.0) 51.4 (29.6 - 85.0) 58.7 (36.0 - 86.0) 53.9 (37.8 - 76.2) 59.2 (38.7 - 85.0)
Min - Max 0.1 - 221.3 0.1 - 221.3 0.1 - 221.3 0.1 - 221.3 0.1 - 221.3 0.1 - 221.3
Missing 13,688 557 2,494
2-Year Mortality
No 23,579 (85.3%) 928 (3.4%) 3,133 (11.3%) 23,579 (85.3%) 928 (3.4%) 3,133 (11.3%)
Yes 0 (0.0%) 380 (15.9%) 2,011 (84.1%) 0 (0.0%) 380 (15.9%) 2,011 (84.1%)
2-Year Outcome
Alive w/o Kidney Failure 23,579 (86.6%) 515 (1.9%) 3,133 (11.5%) 23,579 (86.6%) 515 (1.9%) 3,133 (11.5%)
Kidney Failure 0 (0.0%) 793 (100.0%) 0 (0.0%) 0 (0.0%) 793 (100.0%) 0 (0.0%)
Death w/o Kidney Failure 0 (0.0%) 0 (0.0%) 2,011 (100.0%) 0 (0.0%) 0 (0.0%) 2,011 (100.0%)
5-Year Mortality
No 23,579 (97.2%) 682 (2.8%) 0 (0.0%) 23,579 (97.2%) 682 (2.8%) 0 (0.0%)
Yes 0 (0.0%) 626 (10.8%) 5,144 (89.2%) 0 (0.0%) 626 (10.8%) 5,144 (89.2%)

7 Table Sup - Distribution of Healthcare’s Networks with data from VISARE

# Tabla 1a
imp.datosA |> 
  filter(.imp == 0) |> 
  gtsummary::tbl_summary(
    include = c(cas_cat, cas), 
    statistic = all_continuous() ~ c(
      "{mean} ({sd})",
      "{median} ({p25} - {p75})", 
      "{min} - {max}"
    ),
    digits = list(all_continuous() ~ c(1, 1, 1, 1), 
                  all_categorical() ~ c(0, 1)), 
    missing_text = "Missing"
  ) |> 
  bold_labels() |>  
  modify_footnote(everything() ~ NA) -> tab_cas_overall

imp.datosA |> 
  filter(.imp == 0) |> 
  gtsummary::tbl_summary(
    include = c(cas_cat, cas, eventd5ylab), 
    by = eventd5ylab,
    statistic = all_continuous() ~ c(
      "{mean} ({sd})",
      "{median} ({p25} - {p75})", 
      "{min} - {max}"
    ),
    digits = list(all_continuous() ~ c(1, 1, 1, 1), 
                  all_categorical() ~ c(0, 1)), 
    missing_text = "Missing", 
    percent = "row"
  ) |> 
  bold_labels() |>  
  modify_footnote(everything() ~ NA) -> tab_cas_out

imp.datosA |> 
  filter(.imp == 0) |> 
  mutate(acr_miss = if_else(!is.na(acr), 
                            "Datos completos", 
                            "Datos perdidos")) |> 
  gtsummary::tbl_summary(
    include = c(cas_cat, cas), 
    by = acr_miss,
    statistic = all_continuous() ~ c(
      "{mean} ({sd})",
      "{median} ({p25} - {p75})", 
      "{min} - {max}"
    ),
    digits = list(all_continuous() ~ c(1, 1, 1, 1), 
                  all_categorical() ~ c(0, 1)), 
    missing_text = "Missing", 
    percent = "row"
  ) |> 
  bold_labels() |> 
  modify_footnote(everything() ~ NA) -> tab_cas_miss

tbl_merge(list(tab_cas_overall, tab_cas_miss, tab_cas_out), 
          tab_spanner = c("**Total**", "Complete data in all variables used for multiple imputation
(% row)", "**Outcome**")) %>% 
  modify_caption("Table. EsSalud's Healthcare Networks distribution of the study population according missing data and outcome in 3a-3b-4 CKD Stages") %>% 
  bold_labels() -> tab_cas

tab_cas |>  
  as_flex_table() |> 
  flextable::save_as_docx(path = here("Tables", "Main-Winsorize-1_5", "Table_Network_Dist.docx"))

tab_cas |>  
  gtsummary::as_kable_extra() |> 
  kableExtra::kable_styling("striped")
Table. EsSalud's Healthcare Networks distribution of the study population according missing data and outcome in 3a-3b-4 CKD Stages
Total
Complete data in all variables used for multiple imputation
(% row)
Outcome
Characteristic N = 30,031 Datos completos
N = 9,818
Datos perdidos
N = 20,213
Alive w/o Kidney Failure
N = 23,579
Kidney Failure
N = 1,308
Death w/o Kidney Failure
N = 5,144
EsSalud Network
Metropolitan Lima 14,784 (49.2%) 8,897 (60.2%) 5,887 (39.8%) 10,770 (72.8%) 1,097 (7.4%) 2,917 (19.7%)
Other Regions 15,247 (50.8%) 921 (6.0%) 14,326 (94.0%) 12,809 (84.0%) 211 (1.4%) 2,227 (14.6%)
EsSalud Network
Amazonas 54 (0.2%) 7 (13.0%) 47 (87.0%) 48 (88.9%) 0 (0.0%) 6 (11.1%)
Ancash: Anchas (except Huaraz) 2,018 (6.7%) 46 (2.3%) 1,972 (97.7%) 1,700 (84.2%) 32 (1.6%) 286 (14.2%)
Ancash: Huaraz 223 (0.7%) 60 (26.9%) 163 (73.1%) 198 (88.8%) 2 (0.9%) 23 (10.3%)
Apurímac 266 (0.9%) 7 (2.6%) 259 (97.4%) 233 (87.6%) 2 (0.8%) 31 (11.7%)
Arequipa 477 (1.6%) 11 (2.3%) 466 (97.7%) 375 (78.6%) 22 (4.6%) 80 (16.8%)
Ayacucho 537 (1.8%) 8 (1.5%) 529 (98.5%) 469 (87.3%) 6 (1.1%) 62 (11.5%)
Cajamarca 117 (0.4%) 3 (2.6%) 114 (97.4%) 100 (85.5%) 1 (0.9%) 16 (13.7%)
Cusco 295 (1.0%) 5 (1.7%) 290 (98.3%) 246 (83.4%) 3 (1.0%) 46 (15.6%)
Huancavelica 48 (0.2%) 0 (0.0%) 48 (100.0%) 39 (81.3%) 2 (4.2%) 7 (14.6%)
Huánuco 491 (1.6%) 50 (10.2%) 441 (89.8%) 435 (88.6%) 2 (0.4%) 54 (11.0%)
Ica 124 (0.4%) 5 (4.0%) 119 (96.0%) 95 (76.6%) 7 (5.6%) 22 (17.7%)
Junín 197 (0.7%) 13 (6.6%) 184 (93.4%) 164 (83.2%) 2 (1.0%) 31 (15.7%)
La Libertad 1,544 (5.1%) 336 (21.8%) 1,208 (78.2%) 1,209 (78.3%) 74 (4.8%) 261 (16.9%)
Lambayeque 3,477 (11.6%) 108 (3.1%) 3,369 (96.9%) 3,010 (86.6%) 3 (0.1%) 464 (13.3%)
Lima y Callao: Sabogal 84 (0.3%) 4 (4.8%) 80 (95.2%) 63 (75.0%) 1 (1.2%) 20 (23.8%)
Lima: Almenara 3,795 (12.6%) 295 (7.8%) 3,500 (92.2%) 3,037 (80.0%) 57 (1.5%) 701 (18.5%)
Loreto 632 (2.1%) 15 (2.4%) 617 (97.6%) 525 (83.1%) 11 (1.7%) 96 (15.2%)
Madre de Dios 71 (0.2%) 20 (28.2%) 51 (71.8%) 55 (77.5%) 0 (0.0%) 16 (22.5%)
Moquegua 350 (1.2%) 5 (1.4%) 345 (98.6%) 285 (81.4%) 3 (0.9%) 62 (17.7%)
Other 10,905 (36.3%) 8,598 (78.8%) 2,307 (21.2%) 7,670 (70.3%) 1,039 (9.5%) 2,196 (20.1%)
Pasco 566 (1.9%) 50 (8.8%) 516 (91.2%) 506 (89.4%) 1 (0.2%) 59 (10.4%)
Piura 508 (1.7%) 18 (3.5%) 490 (96.5%) 408 (80.3%) 2 (0.4%) 98 (19.3%)
Puno: Juliaca 849 (2.8%) 21 (2.5%) 828 (97.5%) 699 (82.3%) 0 (0.0%) 150 (17.7%)
Puno: Puno (except Juliaca) 592 (2.0%) 18 (3.0%) 574 (97.0%) 494 (83.4%) 5 (0.8%) 93 (15.7%)
San Martín 55 (0.2%) 30 (54.5%) 25 (45.5%) 47 (85.5%) 0 (0.0%) 8 (14.5%)
San Martín: Moyobamba 492 (1.6%) 12 (2.4%) 480 (97.6%) 417 (84.8%) 4 (0.8%) 71 (14.4%)
Tacna 978 (3.3%) 55 (5.6%) 923 (94.4%) 816 (83.4%) 20 (2.0%) 142 (14.5%)
Tumbes 83 (0.3%) 0 (0.0%) 83 (100.0%) 64 (77.1%) 3 (3.6%) 16 (19.3%)
Ucayali 203 (0.7%) 18 (8.9%) 185 (91.1%) 172 (84.7%) 4 (2.0%) 27 (13.3%)

8 Coverage map of study population

df <- imp.datosA |> 
  filter(.imp == 0) |> 
  count(region_peru) |> 
  mutate(region_peru = if_else(region_peru == "Ancash", "Áncash", region_peru))

# Obtener los límites de los departamentos del Perú
peru_departments <- ne_states(country = "Peru", returnclass = "sf")

# Crear una nueva columna 'name_grouped' donde agrupamos 'Lima', 'Lima Province' y 'Callao'
peru_departments <- peru_departments %>%
  mutate(name_grouped = case_when(
    name %in% c("Lima", "Lima Province", "Callao") ~ "Lima Metropolitana",
    TRUE ~ name
  ))

# Fusionar los polígonos de 'Lima', 'Lima Province' y 'Callao'
peru_departments_grouped <- peru_departments %>%
  group_by(name_grouped) %>%
  summarize(geometry = st_union(geometry))

# Filtrar los nombres de los departamentos
peru_departments_grouped <- peru_departments_grouped  |>  
  select(name_grouped)

# Fusionar los datos geoespaciales con tu dataset
merged_data <- peru_departments_grouped %>%
  left_join(df, by = c("name_grouped" = "region_peru"))

# Crear una nueva columna para los rangos de cobertura
merged_data <- merged_data %>%
  mutate(n_cat = cut(n, 
                     breaks = c(-Inf, 50, 100, 200, 500, 1000, 2000, 3000, 5000, 10000, Inf), 
                     labels = c("40-50", "50-100", "100-200", "200-500", "500-1000",  
                                "1000 -2000", "2000-3000", "3000-5000", "5000-10000", "10000+")))

# Obtener los límites de los países de Sudamérica
south_america <- ne_countries(continent = "South America", returnclass = "sf")

# Crear el mapa de Sudamérica
map_south_america <- ggplot(data = south_america) +
  geom_sf(fill = "white", color = "black") +
  geom_sf(data = subset(south_america, name == "Peru"), fill = "grey70") +
  geom_sf(data = merged_data, aes(fill = n_cat), alpha = 0.8) + 
  scale_fill_brewer(palette = "Spectral", na.value = "grey50", direction = -1) +
  theme_minimal() + 
  theme(legend.position = "right") + 
  coord_sf(xlim = c(-80, 15), 
           ylim = c(-60, 20)) +  # Ajustar límites del eje X
  labs(fill = "Sample Size")

map_coverage <- map_south_america +
  geom_magnify(aes(from = name == "Peru"), 
               to = c(-30, 10, -50, 10), 
               shadow = FALSE, 
               linewidth = 0.4, 
               colour = "black")

ggsave(filename = "map_coverage.jpeg", 
       plot = map_coverage, 
       device = "jpeg",
       path = here("Figures", "Main-Winsorize-1_5"), 
       scale = 3, 
       width = 6, 
       height = 6, 
       units = "cm", 
       dpi = 1000
       )
include_graphics(here("Figures", "Main-Winsorize-1_5", "map_coverage.jpeg"))

9 Cumulative incidence function for competing risks data in all imputed data

Figure shows the cumulative incidence curves of renal failure and pre-renal failure death in the study patients.

# Seleccion del grupo 3a-4----
dataA <- imp.datosA |> 
  filter(.imp == 0) 

tidycmprsk::cuminc(Surv(time, eventdf) ~ 1, dataA) -> cif

cif |> 
  tidy(times = 1:5) |> 
  select(time, outcome, n.event, n.risk, n.censor, estimate, conf.low, conf.high) |> 
  mutate(across(c(estimate, conf.low, conf.high), ~ round(100 * .x, 2)), 
         outcome = as.character(outcome),
         n = str_glue("{n.event} / {n.risk} ({n.censor})"), 
         inc = str_glue("{estimate}% ({conf.low}% to {conf.high}%)")) |> 
  select(time, outcome, n, inc) |> 
  pivot_wider(id_cols = time, names_from = outcome, values_from = c(n, inc)) |> 
  select(time, n_1, inc_1, n_2, inc_2) |> 
  flextable() |> 
    add_header_row(values = c("Year", "Kidney failure", "Death without kidney failure"), colwidths = c(1, 2, 2))  |> 
  set_header_labels(
    time = "Year", 
    n_1 = "Event / Total (Censor)", 
    inc_1 = "Cumulative Incidence (95%CI)", 
    n_2 = "Event / Total (Censor)", 
    inc_2 = "Cumulative Incidence (95%CI)" 
  ) |> 
  merge_v(j = 1, part = "header") |> 
  set_caption("Table. Cumulative incidence of kidney failure and death without kidney failure in patients with CKD stages 3a-3b-4") %>% 
  theme_box() |> 
  autofit() -> tab_cif1

tab_cif1 %>% 
  save_as_docx(path = here("Tables", "Main-Winsorize-1_5", "Table_CI_KF_3a4_imputed.docx"))

tab_cif1

Year

Kidney failure

Death without kidney failure

Event / Total (Censor)

Cumulative Incidence (95%CI)

Event / Total (Censor)

Cumulative Incidence (95%CI)

1

442 / 27617 (1053)

1.49% (1.36% to 1.63%)

919 / 27617 (1053)

3.1% (2.91% to 3.31%)

2

351 / 24801 (1373)

2.73% (2.55% to 2.92%)

1092 / 24801 (1373)

6.96% (6.67% to 7.26%)

3

254 / 22801 (600)

3.66% (3.45% to 3.88%)

1146 / 22801 (600)

11.16% (10.8% to 11.53%)

4

167 / 18369 (3212)

4.32% (4.09% to 4.56%)

1062 / 18369 (3212)

15.36% (14.93% to 15.79%)

5

94 / 14008 (3333)

4.76% (4.51% to 5.02%)

925 / 14008 (3333)

19.71% (19.22% to 20.2%)

# Seleccion del grupo 3a-4----
dataA <- imp.datosA |> 
  filter(.imp == 0)

cmprsk::cuminc(ftime = dataA$time5y, 
       fstatus = dataA$eventd5ylab, 
       cencode = "Alive w/o Kidney Failure") -> cif

ciplotdat <- 
  cif %>% 
  list_modify("Tests" = NULL) %>% 
  map_df(`[`, c("time", "est", "var"), .id = "id") %>% 
  mutate(id = recode(
    id, 
    "1 Death w/o Kidney Failure" = "Death w/o Kidney Failure", 
    "1 Kidney Failure" = "Kidney Failure"), 
    ll = est - 1.96 * sqrt(var), 
    ul = est + 1.96 * sqrt(var)
    ) %>% 
  rename(
    event = id
  )

ciplotdat %>% 
  ggplot(aes(x = time, y = est)) +
  geom_ribbon(aes(ymin = ll, ymax = ul, fill = event), 
              alpha = 0.25, linetype = 0) + 
  geom_step(lwd = 0.5, aes(color = event)) +
  theme_survminer() +
  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + 
  labs(x = "Years", 
       y = "Cumulative incidence",
       title = NULL) + 
  theme(legend.position = "top",
        legend.title = element_blank(), 
        legend.background = element_rect(fill = "white"), 
        legend.key.size = unit(0.2, "cm")) -> g1

ciplotdat %>% 
  filter(event == "Kidney Failure") %>%
  ggplot(aes(x = time, y = est)) +
  geom_ribbon(aes(ymin = ll, ymax = ul), fill = "#89E1E3", 
              alpha = 0.1, linetype = 0) + 
  geom_step(lwd = 0.5, color = "#89E1E3") +
  theme_survminer() +
  ylim(c(0, 0.06)) +
  scale_y_continuous(labels = scales::percent, limits = c(0, 0.06)) + 
  labs(x = "", 
       y = "",
       title = "") -> g2

kf_fit <- survfit(
  Surv(time5y, ifelse(eventd5y != 0, 1, 0)) ~ 1, 
  data = dataA
)

num <- ggsurvplot(
  fit = kf_fit, 
  risk.table = "nrisk_cumevents", 
  risk.table.y.text = FALSE,
  risk.table.y.text.col = FALSE, 
  tables.y.text = FALSE, 
  tables.y.text.col = FALSE, 
  ylab = "Years",
  risk.table.fontsize = 3,
  tables.theme = theme_survminer(font.main = 9)
  )

cowplot::plot_grid(
  g1, 
  num$table + theme_cleantable(), 
  nrow = 2, 
  rel_heights = c(4, 1), 
  align = "v", 
  axis = "b"
  ) -> g3

g3 + inset_element(g2, 0.15, 0.50, 1, 0.94,  
                   align_to = 'full',  
                   ignore_tag = TRUE) -> plot_cif_mh

ggsave(filename = "Plot_CIF_imputed.jpeg", 
      plot = plot_cif_mh, 
      device = "jpeg", 
      path = here("Figures", "Main-Winsorize-1_5"), 
      dpi = 1000, 
      scale = 2, 
      width = 9,
      height = 9, 
      units = "cm", 
      bg = "white")
knitr::include_graphics(here("Figures", "Main-Winsorize-1_5", "Plot_CIF_imputed.jpeg"))

Cumulative incidence function curves for kidney failure (sky-blue line) and death before kidney failure (red line) in patients with (A) CKD stages 3a-3b-4 and (B) CKD stages 3b-4

10 SFig - Predictors Distribution

datos_viol_imp <- imp.datosA |> 
  filter(.imp != 0) |> 
  summarise(across(c(age, crea, eGFR_ckdepi, log_acr, log_urine_crea, 
                     log_urine_album), ~mean(.x, na.rm = TRUE)), .by = .id) |> 
  select(age, crea, eGFR_ckdepi, log_acr, log_urine_crea, log_urine_album) |> 
  mutate(group = "Imputed") 
  


datos_viol <-  imp.datosA |> 
  filter(.imp == 0) |> 
  select(age, crea, eGFR_ckdepi, log_acr, log_urine_crea, log_urine_album) |> 
  mutate(group = "Available data") |> 
  bind_rows(datos_viol_imp) 

p <- datos_viol |> 
  pivot_longer(cols = c(age, crea, eGFR_ckdepi, log_acr, log_urine_crea, 
                        log_urine_album), names_to = "predictor", 
               values_to = "value") |> 
  mutate(predictor = case_match(predictor, 
                                "age" ~ "Age (years)", 
                                "crea" ~ "Serum Creatinine (mg/dL)", 
                                "eGFR_ckdepi" ~ "eGFR (ml/min/1.73m²)", 
                                "log_acr" ~ "Log uACR (mg/g)", 
                                "log_urine_crea" ~ "Log Urine Creatinine (mg/dL)", 
                                "log_urine_album" ~ "Log Urine Albumin (mg/ml)", 
                                .default = predictor)) |> 
  ggviolin(x = "group", y = "value", fill = "group", 
           add = "boxplot", 
           add.params = list(fill = "white"), 
           width = 0.5, 
           alpha = 0.5) 

p <- facet(p, facet.by = "predictor", scales = "free_y") + 
  labs(x = NULL, y = NULL, fill = NULL) + 
  scale_fill_npg("nrc")

ggsave(filename = "predictor_dist_overall.jpeg", 
       plot = p, 
       device = "jpeg", 
       path = here("Figures", "Main-Winsorize-1_5"), 
       scale = 2, 
       width = 12, 
       height = 8, 
       units = "cm", 
       dpi = 1000)
include_graphics(here("Figures", "Main-Winsorize-1_5", "predictor_dist_overall.jpeg"))

11 SFig - Predicted Risks Distribution

gc()
            used   (Mb) gc trigger   (Mb)   max used   (Mb)
Ncells   7466383  398.8   13505476  721.3   13505476  721.3
Vcells 491600984 3750.7 1188086323 9064.4 1188086323 9064.4
datos_viol_imp <- imp.datosA |> 
  filter(.imp != 0) |> 
  summarise(across(c(risk2y, risk5y), ~mean(.x, na.rm = TRUE)), .by = .id) |> 
  select(risk2y, risk5y) |> 
  mutate(group = "Imputed") 

datos_viol <-  imp.datosA |> 
  filter(.imp == 0) |> 
  summarise(across(c(risk2y, risk5y), ~mean(.x, na.rm = TRUE)), .by = .id) |> 
  select(risk2y, risk5y) |> 
  mutate(group = "Available data") |> 
  bind_rows(datos_viol_imp)

p1 <- datos_viol |> 
  filter(group == "Available data") |> 
  ggplot(aes(x = risk2y, y = stat(count / sum(count)))) + 
  geom_histogram(bins = 30, fill = mypal[1], alpha = 0.5, color = "black", 
                 linewidth = 0.1) + 
  theme_classic() +
  scale_y_continuous(labels = percent_format()) + 
  labs(y = "%", x = "2-year KFRE's predicted risk", 
       title = "Available data") + 
  theme(plot.title = element_text(hjust = 0.5)) 

p2 <- imp.datosA |> 
  filter(.imp != 0) |> 
  ggplot(aes(x = risk2y, y = stat(count / sum(count)))) + 
  geom_histogram(bins = 30, fill = mypal[2], alpha = 0.5, color = "black", 
                 linewidth = 0.1) + 
  theme_classic() +
  scale_y_continuous(labels = percent_format()) + 
  labs(y = "%", x = "2-year KFRE's predicted risk", 
       title = "Imputed") + 
  theme(plot.title = element_text(hjust = 0.5))

p3 <- datos_viol |> 
  filter(group == "Available data") |> 
  ggplot(aes(x = risk5y, y = stat(count / sum(count)))) + 
  geom_histogram(bins = 30, fill = mypal[1], alpha = 0.5, color = "black", 
                 linewidth = 0.1) + 
  theme_classic() +
  scale_y_continuous(labels = percent_format()) + 
  labs(y = "%", x = "5-year KFRE's predicted risk", 
       title = "Available data") + 
  theme(plot.title = element_text(hjust = 0.5)) 

p4 <- imp.datosA |> 
  filter(.imp != 0) |> 
  ggplot(aes(x = risk5y, y = stat(count / sum(count)))) + 
  geom_histogram(bins = 30, fill = mypal[2], alpha = 0.5, color = "black", 
                 linewidth = 0.1) + 
  theme_classic() +
  scale_y_continuous(labels = percent_format()) + 
  labs(y = "%", x = "5-year KFRE's predicted risk", 
       title = "Imputed") + 
  theme(plot.title = element_text(hjust = 0.5))

p_predicted <- (p1 / p2) | (p3 / p4)

ggsave(filename = "predicted_risk.jpeg", 
       plot = p_predicted, device = "jpeg", 
       path = here("Figures", "Main-Winsorize-1_5"), 
       scale = 2, 
       width = 9, 
       height = 12, 
       units = "cm", 
       dpi = 1000)
include_graphics(here("Figures", "Main-Winsorize-1_5", "predicted_risk.jpeg"))

12 Table Sup - Time distribution

  • Time distribution in non-imputed data
imp.datosA |> 
  filter(.imp == 0) |> 
  summarise(median = median(time, na.rm = TRUE), 
            min = min(time, na.rm = TRUE), 
            p25 = quantile(time, probs = 0.25, na.rm = TRUE), 
            p75 = quantile(time, probs = 0.75, na.rm = TRUE), 
            max = max(time, na.rm = TRUE)) |> 
  kbl() |> 
  kable_styling()
median min p25 p75 max
4.936345 0.0027379 3.08282 7.407255 9.995893
  • Time distribution in pooled data
imp.datosA |> 
  filter(.imp != 0) |> 
  group_by(.imp) |> 
  summarise(median = median(time, na.rm = TRUE), 
            min = min(time, na.rm = TRUE), 
            p25 = quantile(time, probs = 0.25, na.rm = TRUE), 
            p75 = quantile(time, probs = 0.75, na.rm = TRUE), 
            max = max(time, na.rm = TRUE)) |> 
  ungroup() |> 
  summarise(across(c(median, min, p25, p75, max), ~mean(.x, na.rm = TRUE))) |> 
  kbl() |> 
  kable_styling()
median min p25 p75 max
4.936345 0.0027379 3.08282 7.407255 9.995893
  • Time distribution in each imputed dataset:
imp.datosA |> 
  group_by(.imp) |> 
  summarise(median = median(time, na.rm = TRUE), 
            min = min(time, na.rm = TRUE), 
            p25 = quantile(time, probs = 0.25, na.rm = TRUE), 
            p75 = quantile(time, probs = 0.75, na.rm = TRUE), 
            max = max(time, na.rm = TRUE))  |> 
  ungroup() |> 
  kbl() |> 
  kable_styling()
.imp median min p25 p75 max
0 4.936345 0.0027379 3.08282 7.407255 9.995893
1 4.936345 0.0027379 3.08282 7.407255 9.995893
2 4.936345 0.0027379 3.08282 7.407255 9.995893
3 4.936345 0.0027379 3.08282 7.407255 9.995893
4 4.936345 0.0027379 3.08282 7.407255 9.995893
5 4.936345 0.0027379 3.08282 7.407255 9.995893
6 4.936345 0.0027379 3.08282 7.407255 9.995893
7 4.936345 0.0027379 3.08282 7.407255 9.995893
8 4.936345 0.0027379 3.08282 7.407255 9.995893
9 4.936345 0.0027379 3.08282 7.407255 9.995893
10 4.936345 0.0027379 3.08282 7.407255 9.995893
11 4.936345 0.0027379 3.08282 7.407255 9.995893
12 4.936345 0.0027379 3.08282 7.407255 9.995893
13 4.936345 0.0027379 3.08282 7.407255 9.995893
14 4.936345 0.0027379 3.08282 7.407255 9.995893
15 4.936345 0.0027379 3.08282 7.407255 9.995893
16 4.936345 0.0027379 3.08282 7.407255 9.995893
17 4.936345 0.0027379 3.08282 7.407255 9.995893
18 4.936345 0.0027379 3.08282 7.407255 9.995893
19 4.936345 0.0027379 3.08282 7.407255 9.995893
20 4.936345 0.0027379 3.08282 7.407255 9.995893
21 4.936345 0.0027379 3.08282 7.407255 9.995893
22 4.936345 0.0027379 3.08282 7.407255 9.995893
23 4.936345 0.0027379 3.08282 7.407255 9.995893
24 4.936345 0.0027379 3.08282 7.407255 9.995893
25 4.936345 0.0027379 3.08282 7.407255 9.995893
26 4.936345 0.0027379 3.08282 7.407255 9.995893
27 4.936345 0.0027379 3.08282 7.407255 9.995893
28 4.936345 0.0027379 3.08282 7.407255 9.995893
29 4.936345 0.0027379 3.08282 7.407255 9.995893
30 4.936345 0.0027379 3.08282 7.407255 9.995893
31 4.936345 0.0027379 3.08282 7.407255 9.995893
32 4.936345 0.0027379 3.08282 7.407255 9.995893
33 4.936345 0.0027379 3.08282 7.407255 9.995893
34 4.936345 0.0027379 3.08282 7.407255 9.995893
35 4.936345 0.0027379 3.08282 7.407255 9.995893
36 4.936345 0.0027379 3.08282 7.407255 9.995893
37 4.936345 0.0027379 3.08282 7.407255 9.995893
38 4.936345 0.0027379 3.08282 7.407255 9.995893
39 4.936345 0.0027379 3.08282 7.407255 9.995893
40 4.936345 0.0027379 3.08282 7.407255 9.995893
41 4.936345 0.0027379 3.08282 7.407255 9.995893
42 4.936345 0.0027379 3.08282 7.407255 9.995893
43 4.936345 0.0027379 3.08282 7.407255 9.995893
44 4.936345 0.0027379 3.08282 7.407255 9.995893
45 4.936345 0.0027379 3.08282 7.407255 9.995893
46 4.936345 0.0027379 3.08282 7.407255 9.995893
47 4.936345 0.0027379 3.08282 7.407255 9.995893
48 4.936345 0.0027379 3.08282 7.407255 9.995893
49 4.936345 0.0027379 3.08282 7.407255 9.995893
50 4.936345 0.0027379 3.08282 7.407255 9.995893
51 4.936345 0.0027379 3.08282 7.407255 9.995893
52 4.936345 0.0027379 3.08282 7.407255 9.995893
53 4.936345 0.0027379 3.08282 7.407255 9.995893
54 4.936345 0.0027379 3.08282 7.407255 9.995893
55 4.936345 0.0027379 3.08282 7.407255 9.995893
56 4.936345 0.0027379 3.08282 7.407255 9.995893
57 4.936345 0.0027379 3.08282 7.407255 9.995893
58 4.936345 0.0027379 3.08282 7.407255 9.995893
59 4.936345 0.0027379 3.08282 7.407255 9.995893
60 4.936345 0.0027379 3.08282 7.407255 9.995893
61 4.936345 0.0027379 3.08282 7.407255 9.995893
62 4.936345 0.0027379 3.08282 7.407255 9.995893
63 4.936345 0.0027379 3.08282 7.407255 9.995893
64 4.936345 0.0027379 3.08282 7.407255 9.995893
65 4.936345 0.0027379 3.08282 7.407255 9.995893
66 4.936345 0.0027379 3.08282 7.407255 9.995893
67 4.936345 0.0027379 3.08282 7.407255 9.995893
68 4.936345 0.0027379 3.08282 7.407255 9.995893
69 4.936345 0.0027379 3.08282 7.407255 9.995893
70 4.936345 0.0027379 3.08282 7.407255 9.995893
71 4.936345 0.0027379 3.08282 7.407255 9.995893
72 4.936345 0.0027379 3.08282 7.407255 9.995893
73 4.936345 0.0027379 3.08282 7.407255 9.995893
74 4.936345 0.0027379 3.08282 7.407255 9.995893
75 4.936345 0.0027379 3.08282 7.407255 9.995893
76 4.936345 0.0027379 3.08282 7.407255 9.995893
77 4.936345 0.0027379 3.08282 7.407255 9.995893
78 4.936345 0.0027379 3.08282 7.407255 9.995893
79 4.936345 0.0027379 3.08282 7.407255 9.995893
80 4.936345 0.0027379 3.08282 7.407255 9.995893
81 4.936345 0.0027379 3.08282 7.407255 9.995893
82 4.936345 0.0027379 3.08282 7.407255 9.995893
83 4.936345 0.0027379 3.08282 7.407255 9.995893
84 4.936345 0.0027379 3.08282 7.407255 9.995893
85 4.936345 0.0027379 3.08282 7.407255 9.995893
86 4.936345 0.0027379 3.08282 7.407255 9.995893
87 4.936345 0.0027379 3.08282 7.407255 9.995893
88 4.936345 0.0027379 3.08282 7.407255 9.995893
89 4.936345 0.0027379 3.08282 7.407255 9.995893
90 4.936345 0.0027379 3.08282 7.407255 9.995893
91 4.936345 0.0027379 3.08282 7.407255 9.995893
92 4.936345 0.0027379 3.08282 7.407255 9.995893
93 4.936345 0.0027379 3.08282 7.407255 9.995893
94 4.936345 0.0027379 3.08282 7.407255 9.995893
95 4.936345 0.0027379 3.08282 7.407255 9.995893
96 4.936345 0.0027379 3.08282 7.407255 9.995893
97 4.936345 0.0027379 3.08282 7.407255 9.995893
98 4.936345 0.0027379 3.08282 7.407255 9.995893
99 4.936345 0.0027379 3.08282 7.407255 9.995893
100 4.936345 0.0027379 3.08282 7.407255 9.995893

13 Table Sup - Rates

  • Rates in non-imputed data
imp.datosA |> 
  filter(.imp == 0) |> 
  summarise(rate = sum(eventd == 1) / (sum(time))) |> 
  kbl() |> 
  kable_styling()
rate
0.0094819
  • Rates in pooled imputed data
imp.datosA |> 
  filter(.imp != 0) |> 
  group_by(.imp) |> 
  summarise(rate = sum(eventd == 1) / (sum(time))) |> 
  ungroup() |> 
  summarise(across(c(rate), ~mean(.x, na.rm = TRUE))) |> 
  kbl() |> 
  kable_styling()
rate
0.0094819
  • Rates in each imputed data
imp.datosA |> 
  filter(.imp != 0) |> 
  group_by(.imp) |> 
  summarise(rate = sum(eventd == 1) / (sum(time))) |> 
  ungroup() |> 
  kbl() |> 
  kable_styling()
.imp rate
1 0.0094819
2 0.0094819
3 0.0094819
4 0.0094819
5 0.0094819
6 0.0094819
7 0.0094819
8 0.0094819
9 0.0094819
10 0.0094819
11 0.0094819
12 0.0094819
13 0.0094819
14 0.0094819
15 0.0094819
16 0.0094819
17 0.0094819
18 0.0094819
19 0.0094819
20 0.0094819
21 0.0094819
22 0.0094819
23 0.0094819
24 0.0094819
25 0.0094819
26 0.0094819
27 0.0094819
28 0.0094819
29 0.0094819
30 0.0094819
31 0.0094819
32 0.0094819
33 0.0094819
34 0.0094819
35 0.0094819
36 0.0094819
37 0.0094819
38 0.0094819
39 0.0094819
40 0.0094819
41 0.0094819
42 0.0094819
43 0.0094819
44 0.0094819
45 0.0094819
46 0.0094819
47 0.0094819
48 0.0094819
49 0.0094819
50 0.0094819
51 0.0094819
52 0.0094819
53 0.0094819
54 0.0094819
55 0.0094819
56 0.0094819
57 0.0094819
58 0.0094819
59 0.0094819
60 0.0094819
61 0.0094819
62 0.0094819
63 0.0094819
64 0.0094819
65 0.0094819
66 0.0094819
67 0.0094819
68 0.0094819
69 0.0094819
70 0.0094819
71 0.0094819
72 0.0094819
73 0.0094819
74 0.0094819
75 0.0094819
76 0.0094819
77 0.0094819
78 0.0094819
79 0.0094819
80 0.0094819
81 0.0094819
82 0.0094819
83 0.0094819
84 0.0094819
85 0.0094819
86 0.0094819
87 0.0094819
88 0.0094819
89 0.0094819
90 0.0094819
91 0.0094819
92 0.0094819
93 0.0094819
94 0.0094819
95 0.0094819
96 0.0094819
97 0.0094819
98 0.0094819
99 0.0094819
100 0.0094819

14 Table Sup - Table Original Equations

Ecuaciones originales:

table_kfre <- data.frame(
  pred = c("2-years", "5-years"), 
  eq = c("$1-{0.9832}^{e^{(-0.2201\\times(\\frac{age}{10}-7.036)+0.2467\\times(male-0.5642)-0.5567\\times(\\frac{eGFR}{5}-7.222)+0.4510\\times(log{(ACR)}-5.137))}}$", 
         "$1-{0.9365}^{e^{(-0.2201\\times(\\frac{age}{10}-7.036)+0.2467\\times(male-0.5642)-0.5567\\times(\\frac{eGFR}{5}-7.222)+0.4510\\times(log{(ACR)}-5.137))}}$")
)
knitr::kable(table_kfre, escape = TRUE, 
             col.names = c("Prediction horizons", 
                           "Original regional equation calibrated for predicted risk of kidney failure"), 
             caption = "Table. KFRE equations externally validated by the study") |> 
  kable_styling()
Table. KFRE equations externally validated by the study
Prediction horizons Original regional equation calibrated for predicted risk of kidney failure
2-years $1-{0.9832}^{e^{(-0.2201\times(\frac{age}{10}-7.036)+0.2467\times(male-0.5642)-0.5567\times(\frac{eGFR}{5}-7.222)+0.4510\times(log{(ACR)}-5.137))}}$
5-years $1-{0.9365}^{e^{(-0.2201\times(\frac{age}{10}-7.036)+0.2467\times(male-0.5642)-0.5567\times(\frac{eGFR}{5}-7.222)+0.4510\times(log{(ACR)}-5.137))}}$

15 Table Sup Coding

table_coding <- data.frame(
  Variable = c("age", "male", "eGFR_ckdepi", "acr"), 
  Coding = c("integer number that indicates the age in completed years", 
             "1 = male; 0 = female", 
             "estimated glomerular filtration rate obtained by CKD-EPI formula in $ml/min/1.73m^2$", 
             "albumin-to-creatinine ratio in mg/g")
)
knitr::kable(table_coding, escape = TRUE, 
             caption = "Table. Coding of variables") |> 
  kable_styling()
Table. Coding of variables
Variable Coding
age integer number that indicates the age in completed years
male 1 = male; 0 = female
eGFR_ckdepi estimated glomerular filtration rate obtained by CKD-EPI formula in $ml/min/1.73m^2$
acr albumin-to-creatinine ratio in mg/g

16 Reproducibility Ticket

sessionInfo()
R version 4.4.1 (2024-06-14)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 24.04 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.12.0 
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0

locale:
 [1] LC_CTYPE=es_ES.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=es_ES.UTF-8        LC_COLLATE=es_ES.UTF-8    
 [5] LC_MONETARY=es_ES.UTF-8    LC_MESSAGES=es_ES.UTF-8   
 [7] LC_PAPER=es_ES.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=es_ES.UTF-8 LC_IDENTIFICATION=C       

time zone: America/Lima
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] survminer_0.4.9     ggpubr_0.6.0        cmprsk_2.2-12      
 [4] tidycmprsk_1.1.0    survival_3.7-0      ggmagnify_0.4.1    
 [7] RColorBrewer_1.1-3  viridis_0.6.5       viridisLite_0.4.2  
[10] rnaturalearth_1.0.1 sf_1.0-17           mice_3.16.0        
[13] scales_1.3.0        ggsci_3.2.0         cowplot_1.1.3      
[16] patchwork_1.2.0     gtsummary_2.0.2     flextable_0.9.6    
[19] kableExtra_1.4.0    knitr_1.48          janitor_2.2.0      
[22] lubridate_1.9.3     forcats_1.0.0       stringr_1.5.1      
[25] dplyr_1.1.4         purrr_1.0.2         readr_2.1.5        
[28] tidyr_1.3.1         tibble_3.2.1        ggplot2_3.5.1      
[31] tidyverse_2.0.0     rio_1.2.2           here_1.0.1         

loaded via a namespace (and not attached):
  [1] wk_0.9.3                      rstudioapi_0.16.0            
  [3] jsonlite_1.8.8                shape_1.4.6.1                
  [5] magrittr_2.0.3                jomo_2.7-6                   
  [7] farver_2.1.2                  cardx_0.2.1                  
  [9] nloptr_2.1.1                  rmarkdown_2.28               
 [11] ragg_1.3.2                    vctrs_0.6.5                  
 [13] minqa_1.2.8                   askpass_1.2.0                
 [15] terra_1.7-78                  rstatix_0.7.2                
 [17] htmltools_0.5.8.1             haven_2.5.4                  
 [19] survey_4.4-2                  broom_1.0.6                  
 [21] s2_1.1.7                      mitml_0.4-5                  
 [23] KernSmooth_2.23-24            htmlwidgets_1.6.4            
 [25] zoo_1.8-12                    uuid_1.2-1                   
 [27] commonmark_1.9.1              lifecycle_1.0.4              
 [29] iterators_1.0.14              pkgconfig_2.0.3              
 [31] Matrix_1.7-0                  R6_2.5.1                     
 [33] fastmap_1.2.0                 rnaturalearthhires_1.0.0.9000
 [35] snakecase_0.11.1              digest_0.6.37                
 [37] colorspace_2.1-1              rprojroot_2.0.4              
 [39] textshaping_0.4.0             labeling_0.4.3               
 [41] fansi_1.0.6                   km.ci_0.5-6                  
 [43] timechange_0.3.0              httr_1.4.7                   
 [45] abind_1.4-5                   compiler_4.4.1               
 [47] proxy_0.4-27                  fontquiver_0.2.1             
 [49] withr_3.0.1                   backports_1.5.0              
 [51] carData_3.0-5                 DBI_1.2.3                    
 [53] highr_0.11                    ggsignif_0.6.4               
 [55] pan_1.9                       MASS_7.3-61                  
 [57] openssl_2.2.1                 classInt_0.4-10              
 [59] tools_4.4.1                   units_0.8-5                  
 [61] zip_2.3.1                     nnet_7.3-19                  
 [63] glue_1.7.0                    nlme_3.1-165                 
 [65] gridtext_0.1.5                grid_4.4.1                   
 [67] generics_0.1.3                gtable_0.3.5                 
 [69] labelled_2.13.0               tzdb_0.4.0                   
 [71] KMsurv_0.1-5                  class_7.3-22                 
 [73] data.table_1.16.0             hms_1.1.3                    
 [75] sp_2.1-4                      xml2_1.3.6                   
 [77] car_3.1-2                     utf8_1.2.4                   
 [79] markdown_1.13                 foreach_1.5.2                
 [81] pillar_1.9.0                  mitools_2.4                  
 [83] splines_4.4.1                 ggtext_0.1.2                 
 [85] lattice_0.22-5                tidyselect_1.2.1             
 [87] fontLiberation_0.1.0          fontBitstreamVera_0.1.1      
 [89] gridExtra_2.3                 svglite_2.1.3                
 [91] xfun_0.47                     hardhat_1.4.0                
 [93] stringi_1.8.4                 yaml_2.3.10                  
 [95] pacman_0.5.1                  boot_1.3-30                  
 [97] evaluate_0.24.0               codetools_0.2-20             
 [99] officer_0.6.6                 gdtools_0.4.0                
[101] cli_3.6.3                     rpart_4.1.23                 
[103] xtable_1.8-4                  systemfonts_1.1.0            
[105] munsell_0.5.1                 survMisc_0.5.6               
[107] Rcpp_1.0.13                   jpeg_0.1-10                  
[109] lme4_1.1-35.5                 glmnet_4.1-8                 
[111] e1071_1.7-14                  rlang_1.1.4                  
[113] cards_0.2.2